/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 *
 * $Id: BehaviourTypes.hpp,v 1.6 2009-05-13 07:18:16 amaula Exp $
 *
 * \file
 * \brief MaCI - Behaviour Interface Type definition header
 * \author Matthieu Myrsky <matthieu.myrsky@tkk.fi>
 *
 * 
 */
#ifndef _MACI_BEHAVIOUR_DRIVE_TYPES_
#define _MACI_BEHAVIOUR_DRIVE_TYPES_
#include <inttypes.h>
#include "timestamp.hpp"

namespace MaCI {

  /** MaCI - Behaviour interface.
   *
   * This namespace contains all types, methods and helper classes
   * for implementing a Behaviour interface for MaCI.
   */
  namespace Behaviour {

    /** Behaviour element types.
     * 
     * This enumeration defines the available elements for Behaviour interface.
     *
     */
    enum EBehaviourElementType { 
      KTypeUnknown                    = -1, ///< Unknown type
      KTypeCommand                    = 0,
      KTypeBehaviourControl           = 1,
      KTypeBehaviourControlSpeed      = 2,
      KTypeBehaviourInformation       = 3,
      KTypeBehaviourState             = 4

    };

    /** Behaviour commands.
     *
     * Behaviour commands for the 'TCommand' structure. Defined in global
     * 'Behaviour' namespace because otherwise l^Husers would complain :)
     */
    enum EBehaviourCommand { 
      KCommandUnknown             = 0,  ///< Unkown command
      KCommandStart                      = 1,
      KCommandStop                       = 2,
      KCommandGetInfo                    = 3,
      KCommandGetInfoReply               = 4,
      KCommandBehaviourControlEvent      = 5,
      KCommandBehaviourStateEvent        = 6,
      KCommandGetBehaviourStateEvent     = 7
    };

    /**
     * Defines the type of the behaviour
     */
    enum EBehaviourType{
      KBehaviourTypeNormal             = 0,  ///< Normal behaviours commands are 
                                             ///  used when protective behaviours
                                             ///  don't give their commands
      KBehaviourTypeAiding             = 1,  ///< Aiding behaviours command when 
                                             ///  the the robot is moving.
      KBehaviourTypeProtective         = 2   ///< Protective behaviours overrides 
                                             ///  all other behaviour-type commands
    };

    /** Behaviour interface command.
     *
     * Describes a Command for the Behaviour interface. 
     * Commands may required additional dataelements, 
     * and are specified in the descriptions of the commands.
     */
    struct TCommand {
      TCommand(EBehaviourCommand aCmd = KCommandUnknown) 
	: cmd(aCmd) {}
      
      uint32_t cmd; ///< Command value
    };

    /**
     * Struct for defining control vector given by behaviour
     *
     * @param aSpeed        Speed value of the control vector
     * @param aAngle        Angle of the control vector
     */
    struct TBehaviourControl{
      TBehaviourControl(float aSpeed= 0.0,
                        float aAngle= 0.0):
        speed(aSpeed),
        angle(aAngle){}

      float speed;
      float angle;
    };


    /**
     * Struct for defining behaviour control by speed and angular speed
     *
     * @param aSpeed        Speed value of beahviour control
     * @param aAngularSpeed AngularSpeed value of behaviour control
     */
    struct TBehaviourControlSpeed{
      TBehaviourControlSpeed(float aSpeed = 0.0,
                             float aAngularSpeed = 0.0):
        speed(aSpeed),
        angularSpeed(aAngularSpeed){}


      float speed;
      float angularSpeed;
    };

    /**
     * Struct for telling the state of the behaviour
     * 0 for off, else running
     */
    struct TBehaviourState{
      TBehaviourState(uint32_t aState = 0):
        state(aState){}

        uint32_t state;
    };
    /**
     * Structure for defining some 'nice to know' information 
     * about the behaviour
     *
     * @param aType         Type of the Behaviour
     *
     * \see EBehaviourType
     */
    struct TBehaviourInformation{
      TBehaviourInformation(EBehaviourType aType =KBehaviourTypeNormal)
        :type(aType){}

      EBehaviourType type;
    };
                            

  }

}
#endif
